from time import time, strftime, sleep
from datetime import date, timedelta
from platform import system

END = '\033[0m'


class Color:
    @staticmethod
    def _wrap_colour(colour, args, prints, sep) -> str:
        if prints:
            for a in args:
                print(colour + f'{a}' + END)  # Linux上会报错
        return colour + sep.join(f'{a}' for a in args) + END

    @classmethod
    def background(cls, *args, prints=True, sep=' ') -> str:
        return cls._wrap_colour('\033[0;7m', args, prints, sep)

    @classmethod
    def background_yellow(cls, *args, prints=False, sep=' ') -> str:
        return cls._wrap_colour('\033[033;7m', args, prints, sep)

    @classmethod
    def blue(cls, *args, prints=True, sep=' ') -> str:
        return cls._wrap_colour('\033[94m', args, prints, sep)

    @classmethod
    def cyan(cls, *args, prints=True, sep=' ') -> str:
        return cls._wrap_colour('\033[96m', args, prints, sep)

    @classmethod
    def dark_blue(cls, *args, prints=False, sep=' ') -> str:
        return cls._wrap_colour('\033[34m', args, prints, sep)

    @classmethod
    def dark_cyan(cls, *args, prints=False, sep=' ') -> str:
        return cls._wrap_colour('\033[36m', args, prints, sep)

    @classmethod
    def dark_red(cls, *args, prints=False, sep=' ') -> str:
        return cls._wrap_colour('\033[031m', args, prints, sep)

    @classmethod
    def pink(cls, *args, prints=True, sep=' ') -> str:
        return cls._wrap_colour('\033[95m', args, prints, sep)

    @classmethod
    def red(cls, *args, prints=True, sep=' ') -> str:
        return cls._wrap_colour('\033[91m', args, prints, sep)

    @classmethod
    def yellow(cls, *args, prints=True, sep=' ') -> str:
        return cls._wrap_colour('\033[93m', args, prints, sep)

    @classmethod
    def highlight(cls, text, word) -> None:
        """文本高亮"""
        highlight_word = cls.background_yellow(word)
        len_w = len(word)
        len_t = len(text)
        for i in range(len_t - len_w, -1, -1):
            if text[i: i + len_w] == word:
                text = text[:i] + highlight_word + text[i + len_w:]
        print(text)

    @classmethod
    def hot(cls, value, half=.5) -> str:
        """小于半数打印蓝色，大于半数打印红色"""
        return cls.dark_blue(value) if value < half else cls.dark_red(value)

    @classmethod
    def bar(cls, value, maximum=1, label='') -> str:
        """单柱"""
        length = int(value / maximum * 100)
        if label:
            print(cls.background(label.ljust(length, ' '), prints=False) + cls.hot(value, maximum / 2))
        return '#' * length

    @classmethod
    def bars(cls, values, labels=None) -> None:
        """条形图：https://blog.csdn.net/Yellow_python/article/details/121498190"""
        labels = labels or (str(i) for i in range(len(values)))
        maximum = max(values)
        for value, label in zip(values, labels):
            cls.bar(value, maximum, label)


class _Timer:
    def __init__(self):
        self.t = time()

    def __del__(self):
        if self.__str__():
            print('结束时间：' + strftime('%Y-%m-%d %H:%M:%S'))
            print('运行时间：%s' % self)

    def __str__(self):
        t = self.second
        if t < .5:
            return ''
        elif t < 60:
            return '%.2fs' % t
        elif t < 3600:
            return '%.2fmin' % (t / 60)
        else:
            return '%.2fh' % (t / 3600)

    @property
    def second(self) -> float:
        """程序运行秒数"""
        return time() - self.t


_timer = _Timer()


class Timer(Color):
    def __init__(self):
        self.t = _timer
        self.system = system()

    def __str__(self):
        return str(self.t)

    @staticmethod
    def sleep(secs=1) -> None:
        sleep(secs)

    @property
    def second(self) -> float:
        """程序运行秒数"""
        return self.t.second

    @property
    def now(self) -> str:
        return strftime('%Y-%m-%d %H:%M:%S')

    @property
    def today(self) -> str:
        return strftime('%Y-%m-%d')

    @property
    def yesterday(self) -> str:
        y = date.today() - timedelta(days=1)
        return y.strftime('%Y-%m-%d')

    @property
    def last_month(self) -> str:
        """上个月，格式YYYY-MM"""
        today = date.today()
        last_day_of_last_month = today - timedelta(days=today.day)
        return last_day_of_last_month.strftime('%Y-%m')

    def debug(self, text) -> None:
        """仅在Windows上打印"""
        if self.system == 'Windows':
            self.yellow(text)

    def write_log(self, text, prefix='') -> None:
        with open(prefix + self.today + '.log', 'a', encoding='utf-8') as f:
            f.write(f'{text}\n')


if __name__ == '__main__':
    _t = Timer()
    _t.debug(_t.system)
    _t.write_log(_t.system)
    print(_t.t)
    Timer.blue('blue')
    Timer.cyan('cyan')
    print(_t.dark_blue('dark', 'blue'))
    print(_t.dark_cyan('dark', 'cyan'))
    print(_t.dark_red('dark', 'red'))
    Color.pink('pink')
    Color.red('r', 'e', 'd')
    _t.yellow('yellow')
    _t.background('background', prints=False)
    print(_t.now)
    print(_t.today)
    print(_t.yesterday)
    print(_t.last_month)
    _t.highlight('一片一片又一片', '一片')
    _t.bar(30, 100, 'boy')
    _t.bar(.7, 1, 'girl')
    print(_t.bar(50, 100), 50)
    print(_t.bar(.5, 1), .5)
    _t.bars([1, 2, 3, 4, 5], ['HIVE', 'Flink', 'Spark', 'scikit-learn', 'TensorFlow'])
    _t.bars([1, 2, 3, 4])
    print(_t)
    _t.sleep(1)
    print(_t)
